package core.manager;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;

import core.interfaces.WFQueue;
import core.util.COREServiceRegistry;
import org.apache.log4j.Logger;

/**
 * Classe che gestisce la coda dei Workflows da eseguire. La coda è una LinkedBlockingQueue
 * La Classe WFQueueManager implementa l'interfaccia WFQueue
 * @author Vincenzo Merlo, Scuderi Giovanni Luca, Paolo Giuffrida
 *
 */
public class WFQueueManager implements WFQueue {

    private final Logger logger = COREServiceRegistry.getLogger(WFQueueManager.class.toString());
    private BlockingQueue<Workflow> wfQueue = new LinkedBlockingQueue<Workflow>();

    /**
     *
     */
    public WFQueueManager()
    {super();}

    /**
     * Ritorna il Workflow in testa della coda
     * @return Workflow in testa della coda
     */
    @Override
    public Workflow dequeue() {
        logger.debug("dequeue");
        try {
            final BlockingQueue<Workflow> wf = wfQueue;
            final Workflow workflow;
            synchronized (wf) {
                workflow = wfQueue.take(); //TODO: ottimizzare meccanismo di sincronizzazione
            }

            return workflow;
        } catch (InterruptedException e) {
            logger.error("Error dequeue : " + e.getStackTrace());
        }

        return null;
    }

    /**
     * Inserisce un Workflow nella coda
     * @param Workflow da inserire in cosa
     * @return 1 se l'elemento è stato inserito correttamente; -1 errore
     */
    @Override
    public int enqueue(Workflow wf) {
        logger.debug("enqueue");
        return wfQueue.add(wf) ? 1 : -1;
    }

    /**
     * Ritorna la coda dei Workflows
     * @return BlockingQueue, coda dei Workflows
     */
    public BlockingQueue<Workflow> getWfQueue() {
        logger.debug("getWfQueue");
        return wfQueue;
    }

    /**
     * Setta la coda, BlockingQueue, dei Workflows
     * @param BlockingQueue, coda dei Workflows da settare
     */
    public void setWfQueue(BlockingQueue<Workflow> wfQueue) {
        logger.debug("setWfQueue");
        this.wfQueue = wfQueue;
    }

    /**
     *
     * @return string
     */
    @Override
    public String toString() {
    	StringBuilder sb = new StringBuilder(TQueueManager.class.getSimpleName());
    	for (Workflow wf: this.getWfQueue()) {
    		sb.append("\n\t").append(wf);
    	}

    	return sb.toString();
    }
}